/* Copyright (c) 2004-2022 peigen.info. All rights reserved. */

package info.peigen.hotpot.common.core.result;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import info.peigen.hotpot.common.core.enums.Messageable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <b>(ResultCode)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2021/4/9
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum ResultCode implements Messageable {

    // ===================== 基础码表 =======================
    INITIALIZATION("INITIALIZATION", "初始化"),
    SUCCESS("SUCCESS", "成功"),
    PROCESSING("PROCESSING", "处理中"),
    FAILURE("FAILURE", "执行失败"),

    // ===================== 基础异常码表 =====================
    INTERNAL_ERROR("INTERNAL_ERROR", "内部错误"),
    PARAMETER_ERROR("PARAMETER_ERROR", "参数错误"),
    IDEMPOTENT_ERROR("IDEMPOTENT_ERROR", "幂等错误"),
    UNAUTHENTICATED_ERROR("UNAUTHENTICATED_ERROR", "认证(签名)错误"),
    PARAM_FORMAT_ERROR("PARAM_FORMAT_ERROR", "参数格式错误"),
    REQUEST_NO_NOT_UNIQUE("REQUEST_NO_NOT_UNIQUE", "请求号重复"),
    FIELD_NOT_UNIQUE("FIELD_NOT_UNIQUE", "对象字段重复"),
    REQUEST_GID_NOT_EXIST("REQUEST_GID_NOT_EXIST", "gid不存在"),
    INTERFACE_NOT_REALIZE("INTERFACE_NOT_REALIZE", "该接口未实现"),
    INTERFACE_UNAUTHORIZED("INTERFACE_UNAUTHORIZED", "接口未授权"),

    // ===================== 鉴权相关异常码表 ==================
    EMPTY_CREDENTIAL("EMPTY_CREDENTIAL", "token信息不存在"),
    INVALID_CREDENTIAL("INVALID_CREDENTIAL", "token非法无效"),
    EXPIRED_CREDENTIAL("EXPIRED_CREDENTIAL", "token过期，请重新登录"),


    // ===================== 网关基础异常码表 ==================
    CHANNEL_TIMEOUT("CHANNEL_TIMEOUT", "渠道超时"),
    CHANNEL_GATEWAY_ERROR("CHANNEL_GATEWAY_ERROR", "渠道网关错"),

    // ===================== 加密系统异常码表 ==================
    SECURITY_TYPE_ERROR("SECURITY_TYPE_ERROR", "安全数据类型错"),
    SECURITY_SYSTEM_CONNECT_ERROR("SECURITY_SYSTEM_CONNECT_ERROR", "加密系统连接失败"),
    SECURITY_ENCRYPT_ERROR("SECURITY_ENCRYPT_ERROR", "加密系统加密失败"),
    SECURITY_DECRYPT_ERROR("SECURITY_DECRYPT_ERROR", "加密系统解密失败"),

    // ===================== 管理后台 ==================
    PW_AND_CONFIRMPW_IS_NOT_EQUALS("PW_AND_CONFIRMPW_IS_NOT_EQUALS", "密码和确认密码不一致"),
    OLDPW_NEWPW_IS_EQUALS("OLDPW_NEWPW_IS_EQUALS", "老密码和新密码一致"),
    USER_NOT_LOGIN("USER_NOT_LOGIN", "用户未登录"),
    USER_SUSPEND("USER_SUSPEND", "用户已吊销"),

    // ======================= 默认 ==========================
    /** 不晓得啷格回事 */
    UNKNOWN("0", "不晓得啷格回事"),

    ;

    /** 枚举值 */
    private String code;

    /** 枚举描述 */
    private String message;


    /**
     * 通过枚举<code>code</code>获得枚举
     *
     * @param code 枚举值
     *
     * @return ResultCode
     */
    public static ResultCode getByCode(String code) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.getCode()))
                .findFirst().orElse(UNKNOWN);
    }

    /**
     * 通过枚举<code>name</code>获得枚举
     *
     * @param name 枚举名
     *
     * @return ResultCodeResultCode
     */
    public static ResultCode getByName(String name) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equalsIgnoreCase(name, innerEnum.name()))
                .findFirst().orElse(UNKNOWN);
    }

    /**
     * 获取全部枚举
     *
     * @return List<ResultCode>
     */
    public static List<ResultCode> getAllEnum() {
        return Lists.newArrayList(values());
    }

    /**
     * 获取全部枚举值
     *
     * @return List<String>
     */
    public static List<String> getAllEnumCode() {
        return getAllEnum().stream().map(ResultCode::code).collect(Collectors.toList());
    }

    /**
     * 通过code获取msg
     *
     * @param code 枚举值
     *
     * @return String
     */
    public static String getMsgByCode(String code) {
        return Optional.ofNullable(code).map(
                str ->
                        Optional.ofNullable(getByCode(str))
                                .map(ResultCode::message).orElse(UNKNOWN.message())
        ).orElse(null);
    }

    /**
     * 获取枚举code
     *
     * @param innerEnum 枚举
     *
     * @return code
     */
    public static String getCode(ResultCode innerEnum) {
        return Optional.ofNullable(innerEnum).map(ResultCode::code).orElse(UNKNOWN.code());
    }

    /**
     * 获取全部枚举，封装成Map,Key=Code ,Value=Message
     *
     * @return Map<String, String>
     */
    public static Map<String, String> maps() {
        return getAllEnum().stream().collect(Collectors.toMap(ResultCode::code, ResultCode::message));
    }

    /**
     * 获取全部枚举，封装成Map
     *
     * @return Map<String, ResultCode>
     */
    public static Map<String, ResultCode> getAllEnumMap() {
        return getAllEnum().stream().collect(Collectors.toMap(ResultCode::code, a -> a));
    }

    /**
     * @return Returns the code.
     */
    @Override
    public String code() {
        return code;
    }

    /**
     * @return Returns the message.
     */
    @Override
    public String message() {
        return message;
    }

}